import codecs
import psutil
from datetime import datetime
import util
import config


class Raspi(object):

    @staticmethod
    def get_boot_time():
        return datetime.fromtimestamp(psutil.boot_time()).strftime('%Y-%m-%d %H:%M:%S')

    @staticmethod
    def get_cpu_temperature():
        try:
            with codecs.open('/sys/class/thermal/thermal_zone0/temp', 'r') as f:
                return float(f.readline().strip()) / 1000
        except FileNotFoundError:
            return None

    @staticmethod
    def get_cpu_usage():
        return {
            'percent': psutil.cpu_percent(interval=None, percpu=True),
            'frequency': psutil.cpu_freq().current
        }

    @staticmethod
    def get_memory_usage():
        m = psutil.virtual_memory()
        s = psutil.swap_memory()
        b2h = util.bytes2human

        memory ={
            'total': b2h(m.total),
            'available': b2h(m.available),
            'used': b2h(m.used),
            'buffers': b2h(getattr(m, 'buffers', None)),
            'cached': b2h(getattr(m, 'cached', None)),
            'percent': m.percent,
        }
        swap = {
            'total': b2h(s.total),
            'used': b2h(s.used),
            'percent': s.percent
        }

        return {'memory': memory, 'swap': swap}

    @staticmethod
    def get_disk_usage():
        d = psutil.disk_usage('/')
        b2h = util.bytes2human

        return {'total': b2h(d.total), 'used': b2h(d.used), 'percent': d.percent}

    @staticmethod
    def get_network_usage():
        n = psutil.net_io_counters()
        b2h = util.bytes2human

        return {'sent': b2h(n.bytes_sent), 'receive': b2h(n.bytes_recv)}

    def get_all_data(self):
        cpu_usage = self.get_cpu_usage()
        memory_usage = self.get_memory_usage()
        disk_usage = self.get_disk_usage()
        network_usage = self.get_network_usage()

        data = {
            'device_name': config.device_name,
            'grain': 0,
            'boot_time': self.get_boot_time(),
            'cpu_temperature': self.get_cpu_temperature(),
            'cpu_percent_1': cpu_usage['percent'][0],
            'cpu_percent_2': cpu_usage['percent'][1],
            'cpu_percent_3': cpu_usage['percent'][2],
            'cpu_percent_4': cpu_usage['percent'][3],
            'cpu_percent': sum(cpu_usage['percent'])/4,
            'cpu_frequency': cpu_usage['frequency'],
            'disk_percent': disk_usage['percent'],
            'disk_total': disk_usage['total'],
            'disk_used': disk_usage['used'],
            'memory_available': memory_usage['memory']['available'],
            'memory_buffers': memory_usage['memory']['buffers'],
            'memory_cached': memory_usage['memory']['cached'],
            'memory_percent': memory_usage['memory']['percent'],
            'memory_total': memory_usage['memory']['total'],
            'memory_used': memory_usage['memory']['used'],
            'swap_percent': memory_usage['swap']['percent'],
            'swap_total': memory_usage['swap']['total'],
            'swap_used': memory_usage['swap']['used'],
            'network_receive': network_usage['receive'],
            'network_sent': network_usage['sent'],
        }

        return data


def get_data():
    device = Raspi()
    return device.get_all_data()
